<?php


namespace app\api\logic;


use app\model\freight\Freight;
use support\utils\ContextUtil;
use support\utils\Decimal;

class FreightLogic extends \app\admin\freight\logic\FreightLogic
{


    /**
     * 计算运费
     * @param $goodsItem
     * @param $city_code
     */
    public function calcFreightByShippingTpl($goodsItem, $city_code)
    {
        $tpl = $this->getShippingTpl($goodsItem['shipping_tpl_id']);

        $rule = [];  // 当前规则
        foreach ($tpl['rules'] as $value) {
            if (in_array($city_code, $value['cityList'])) {
                $rule = $value;
                break;
            }
        }

        //计费方式:10=按件数,20=按重量 ,30=按体积
        $total = 0;
        if ($tpl['method'] == Freight::METHOD_NUM) {
            $total = $goodsItem['num'];
        }
        if ($tpl['method'] == Freight::METHOD_WEIGHT) {
            $total = Decimal::newDecimal($goodsItem['num'])->multiply($goodsItem['weight'])->getValue();
        }
        if ($tpl['method'] == Freight::METHOD_VOLUME) {
            $total = Decimal::newDecimal($goodsItem['num'])->multiply($goodsItem['volume'])->getValue();
        }
        //总
        if ($total <= $rule['first']) {
            return $rule['first_fee'];
        }

        // 续
        $additional = $total - $rule['first'];
        if ($additional <= $rule['additional']) {
            return Decimal::newDecimal($rule['first_fee'])
                ->add($rule['additional_fee'])
                ->getValue();
        }

        if ($rule['additional'] < 1) {
            // 配送规则中续件为0
            $additionalFee = 0.00;
        } else {
            //$rule['additional_fee']* $rule['additional'] / $additional
            $additionalFee = Decimal::newDecimal($rule['additional_fee'])
                ->divide($rule['additional'])
                ->multiply($additional)
                ->getValue();
        }
        return Decimal::newDecimal($rule['first_fee'])
            ->add($additionalFee)
            ->getValue();
    }

    /**
     * 验证是否能邮寄
     * @param $shipping_tpl_id
     * @param $city_code
     * @return bool
     */
    public function checkAddress($shipping_tpl_id, $city_code)
    {
        if (!$shipping_tpl_id) {
            return false;
        }
        $res = $this->getShippingTpl($shipping_tpl_id);
        $cityList = [];
        array_map(function ($v) use (&$cityList) {
            $cityList = array_merge($cityList, $v);
        }, array_column($res['rules'], 'cityList'));
        return in_array($city_code, $cityList);
    }

    public function getShippingTpl($shipping_tpl_id)
    {
        if (!$shipping_tpl_id) {
            return null;
        }

        return ContextUtil::getOrSet("shipping_tpl_id" . $shipping_tpl_id, function () use ($shipping_tpl_id) {
            return $this->model->with([
                'rules'
            ])
                ->find($shipping_tpl_id)
                ->toArray();
        });

    }
}